

#include <material/programeditor/programeditordialog.h>
#include <material/programeditor/programoverview.h>
#include <material/programeditor/programtreemodel.h>
#include <session.h>
#include <assert.h>
#include <config.h>

#include <qmessagebox.h>
#include <qsortfilterproxymodel.h>

class cceMaterialProgramFilterModel : public QSortFilterProxyModel
{
private:
	QString	_filter;
	cceMaterialProgramTreeModel*	_model;
public:
	cceMaterialProgramFilterModel (QObject* parent, cceMaterialProgramTreeModel* model)
		: QSortFilterProxyModel (parent)
		, _model (model)
	{
		setSourceModel (model);
    setSortCaseSensitivity(Qt::CaseInsensitive);
    setSortRole(Qt::DisplayRole);
  }

	void SetFilter (const QString &filter)
	{
		_filter = filter;
		invalidateFilter ();
  }

	bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const
	{
		QString name = _model->GetProgramName (source_row);
		if (name.isNull ()) return false;

    return name.contains (_filter, Qt::CaseInsensitive);
	}
};

cceMaterialProgramOverview::cceMaterialProgramOverview (QWidget* parent)
  : cceMaterialOverviewAbstract (parent)
{
	_gui.setupUi(this);

	_model = new cceMaterialProgramTreeModel (cceSession::Get ()->GetMaterialManager ());
	_proxyModel = new cceMaterialProgramFilterModel (this, _model);
  _gui.treeView->setModel (_proxyModel);
  _gui.treeView->sortByColumn(0, Qt::AscendingOrder);

	connect (_gui.treeView->selectionModel (), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
					 this, SLOT(TreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));

	UpdateButtonState ();
}

void cceMaterialProgramOverview::UpdateButtonState ()
{
	QModelIndex index = _gui.treeView->currentIndex ();
	bool enable = index.isValid () && index.internalPointer ();

	_gui.pushButtonAdd->setEnabled (true);
	_gui.pushButtonRemove->setEnabled (enable);
	_gui.pushButtonEdit->setEnabled (enable);
}


cceMaterialEditorAbstract* cceMaterialProgramOverview::CreateEditor(cceMaterialItem *item)
{
  if (item->GetItemType() != cceMaterialItem::ItemType_Program)
    {
      return 0;
    }

  cceMaterialProgram* program = static_cast<cceMaterialProgram*>(item);

  cceMaterialProgramEditorDialog* editor = new cceMaterialProgramEditorDialog (this);
  editor->SetProgram(program);

  return editor;
}

void cceMaterialProgramOverview::Edit(const QModelIndex &srcIndex)
{
  if (!srcIndex.isValid())
    {
      return;
    }

  QModelIndex index = _proxyModel->mapToSource(srcIndex);
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}

  cceMaterialProgram* program = static_cast<cceMaterialProgram*>(index.internalPointer ());
  assert (program);

  emit ShowEditor(program);
}


void cceMaterialProgramOverview::on_pushButtonAdd_clicked ()
{
	cceMaterialProgram* program = new cceMaterialProgram ();
	program->SetName ("unnamed.prog");
  program->SetNew(true);

  emit ShowEditor(program);
}


void cceMaterialProgramOverview::on_pushButtonRemove_clicked ()
{
	QModelIndex index = _gui.treeView->currentIndex ();
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}

  index = _proxyModel->mapToSource(index);
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}


	cceMaterialProgram* program = static_cast<cceMaterialProgram*>(index.internalPointer ());
	assert (program);

	int result = QMessageBox::question (this,
		"Delete program - " CCE_TOOL_NAME,
		tr ("Are you sure you want to delete the program '%1'?").arg (program->GetName ()),
		QMessageBox::Ok, QMessageBox::Cancel);
	if (result == QMessageBox::Ok)
		{
			cceSession::Get ()->GetMaterialManager()->RemoveProgram (program);
		}
}


void cceMaterialProgramOverview::on_pushButtonEdit_clicked ()
{
  QModelIndex index = _gui.treeView->selectionModel()->currentIndex();
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}

  Edit (index);
}

void cceMaterialProgramOverview::on_lineEditFilter_textChanged (const QString &text)
{
	_proxyModel->SetFilter (text);
}

void cceMaterialProgramOverview::on_treeView_activated(const QModelIndex &index)
{
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}
	Edit (index);
}


void cceMaterialProgramOverview::on_pushButtonClearFilter_clicked ()
{
	_gui.lineEditFilter->setText ("");
}


void cceMaterialProgramOverview::TreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)
{
	UpdateButtonState ();
}
